package com.k2data.k2app.service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.k2data.k2app.common.K2Assert;
import com.k2data.k2app.common.MyConstant;
import com.k2data.k2app.common.OrikaMapperFactory;
import com.k2data.k2app.domain.DeviceDTO;
import com.k2data.k2app.domain.EventCond;
import com.k2data.k2app.domain.EventDTO;
import com.k2data.k2app.domain.po.EventCustomer;
import com.k2data.k2app.domain.po.EventDevice;
import com.k2data.k2app.domain.po.EventFault;
import com.k2data.k2app.domain.po.EventMaintenance;
import com.k2data.k2app.domain.po.v1.RFile;
import com.k2data.k2app.exception.K2ResponseException;
import com.k2data.k2app.mapper.EventCustomerMapper;
import com.k2data.k2app.mapper.EventDeviceMapper;
import com.k2data.k2app.mapper.EventFaultMapper;
import com.k2data.k2app.mapper.EventMaintenanceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

/**
 * @author lidong9144@163.com 17-3-20.
 */
@Service
public class EventService {

    private final EventDeviceMapper eventDeviceMapper;
    @Autowired
    private EventV1Service eventV1Service;
    private final EventFaultMapper eventFaultMapper;
    private final EventMaintenanceMapper eventMaintenanceMapper;
    private final EventCustomerMapper eventCustomerMapper;

    @Autowired
    public EventService(EventDeviceMapper eventDeviceMapper, EventFaultMapper eventFaultMapper,
                        EventMaintenanceMapper eventMaintenanceMapper, EventCustomerMapper eventCustomerMapper) {
        this.eventDeviceMapper = eventDeviceMapper;
        this.eventFaultMapper = eventFaultMapper;
        this.eventMaintenanceMapper = eventMaintenanceMapper;
        this.eventCustomerMapper = eventCustomerMapper;
    }

    /**
     * 插入客户事件
     *
     * @param po 实体
     * @return 插入 id
     * @throws K2ResponseException 客户 id 没找到, eventType 没找到
     */
    @Transactional
    public Long insertEventCustomer(EventCustomer po) throws K2ResponseException {
        K2Assert.existCustomerId(po.getCustomerId());

        // TODO eventType 验证

        eventCustomerMapper.insertSelective(po);

        return po.getId();
    }

    @Transactional
    public int updateEventCustomer(EventCustomer po) throws K2ResponseException {
        K2Assert.existCustomerId(po.getCustomerId());

        return eventCustomerMapper.updateByPrimaryKeySelective(po);
    }

    @Transactional
    public Long insertEventFault(EventFault po) throws K2ResponseException {
        K2Assert.existRelationDeviceId(po.getDeviceId());
        K2Assert.existRelationComponentId(po.getComponentId());

        eventFaultMapper.insertSelective(po);

        return po.getId();
    }

    @Transactional
    public int updateEventFault(EventFault po) throws K2ResponseException {
        K2Assert.existRelationDeviceId(po.getDeviceId());
        K2Assert.existRelationComponentId(po.getComponentId());

        return eventFaultMapper.updateByPrimaryKeySelective(po);
    }

    @Transactional
    public Long insertEventMaintenance(EventMaintenance po) throws K2ResponseException {
        K2Assert.existRelationDeviceId(po.getDeviceId());
        K2Assert.existRelationComponentId(po.getComponentId());

        eventMaintenanceMapper.insertSelective(po);

        return po.getId();
    }

    @Transactional
    public int updateEventMaintenance(EventMaintenance po) throws K2ResponseException {
        K2Assert.existRelationDeviceId(po.getDeviceId());
        K2Assert.existRelationComponentId(po.getComponentId());

        return eventMaintenanceMapper.updateByPrimaryKeySelective(po);
    }

    @Transactional
    public Long insertEvent(EventDevice eventDevice) {
        eventDeviceMapper.insertSelective(eventDevice);
        return eventDevice.getId();
    }

    @Transactional
    public Long updateEvent(EventDevice eventDevice) {
        eventDeviceMapper.updateByPrimaryKeySelective(eventDevice);
        return eventDevice.getId();
    }

    public EventDTO getAllEventList(EventCond cond) {
        List<Map<String, String>> typeList = Lists.newArrayList();

        if (cond.getContainEvent() != null && cond.getContainEvent()) {
            Map<String, String> type = Maps.newHashMap();
            type.put("label", "事件");
            type.put("value", MyConstant.EVENT_TYPE);
            typeList.add(type);
        }

        if (cond.getContainFault() != null && cond.getContainFault()) {
            Map<String, String> type = Maps.newHashMap();
            type.put("label", "故障");
            type.put("value", MyConstant.FAULT_TYPE);
            typeList.add(type);
        }

        if (cond.getContainMaintenance() != null && cond.getContainMaintenance()) {
            Map<String, String> type = Maps.newHashMap();
            type.put("label", "维修");
            type.put("value", MyConstant.MAINTENANCE_TYPE);
            typeList.add(type);
        }

        List<EventDTO> list = Lists.newArrayList();

        List<EventDevice> eventList = eventDeviceMapper.selectAllEvent(cond);
        for (EventDevice event : eventList) {
            EventDTO e = OrikaMapperFactory.getMapper().map(event, EventDTO.class);
            if (event.getDevice() != null) {
                DeviceDTO deviceDTO = OrikaMapperFactory.getMapper().map(event.getDevice(), DeviceDTO.class);
                e.setDevice(deviceDTO);
            }
            list.add(e);
        }

        EventDTO dto = new EventDTO();
        dto.setTypes(typeList);
        dto.setEventList(list);

        return dto;
    }

    public List<EventDTO> faultBarChart(EventCond cond) {
        List<EventDTO> list = Lists.newArrayList();

        for (EventFault eventFault : eventFaultMapper.selectTypeCount(cond)) {
            EventDTO dto = new EventDTO();
            dto.setEventType(eventFault.getEventType());
            dto.setCount(eventFault.getCount());

            list.add(dto);
        }

        return list;
    }

    public List<EventDTO> customerTypeCount(EventCond cond) {
        List<EventDTO> list = Lists.newArrayList();

        for (EventCustomer eventFault : eventCustomerMapper.selectTypeCount(cond)) {
            EventDTO dto = new EventDTO();
            dto.setEventType(eventFault.getEventType());
            dto.setCount(eventFault.getCount());

            list.add(dto);
        }

        return list;
    }

    public List<EventDTO> maintenanceBarChart(EventCond cond) {
        List<EventDTO> list = Lists.newArrayList();

        for (EventMaintenance eventMaintenance : eventMaintenanceMapper.selectTypeCount(cond)) {
            EventDTO dto = new EventDTO();
            dto.setEventType(eventMaintenance.getEventType());
            dto.setCount(eventMaintenance.getCount());

            list.add(dto);
        }

        return list;
    }

}
